<?php

namespace mg\crypto;

use \mg\SessionInjection;
use \mg\Injectable;
use \mg\InjectableProvider;

/**
 * A session unique 128 bit token.
 * This token should remain a secret at all times.
 *
 * @author Michiel Hakvoort
 *
 */
class SessionSecretToken implements Injectable {

    public $token = null;

    public function __construct() {
        if($this->token === null) {

            // generate 128 bit hash from 128 bit token
            // temporal addition should reduce hash collision probability
            $this->token = md5(pack('N', mt_rand()) . pack('d', microtime(true)) . pack('N', mt_rand()));
        }
    }

    public function inject() {
        $this->token = new SessionInjection(null);
    }

    public function getToken() {
        return $this->token;
    }

    public function generateSharedToken() {
        // 16 byte, 32 hex length
        $salt = md5(pack('N', mt_rand()) . pack('d', microtime(true)) . pack('N', mt_rand()));

        return $salt . Secure :: pbk($this->token, $salt, 16, 16);
    }

    public function isValidSharedToken($sharedToken) {
        $salt = substr($sharedToken, 0, 32);
        $localSharedToken = $salt . Secure :: pbk($this->token, $salt, 16, 16);

        return $sharedToken === $localSharedToken;
    }



    public static function resolveInstance() {
        return in(function(InjectableProvider $provider) {
            return $provider->createInjectableInstance('mg\crypto\SessionSecretToken');
        });
    }
}